package cloudspace.vm.javassist.tests;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import junit.framework.TestCase;
import cloudspace.vm.VM;


public class JavassistTestCase extends TestCase
{
    // public String realPath = "/home/mjw87/workspace/cloudspace/src";
    public String realPath = System.getProperty( "user.dir" ) + "/src";

    // public ByteCodeRuntime bct;
    public static VM virtualM;


    public void setUp()
    {

        virtualM = VM.lookupVM( realPath );
        virtualM.enter();

    }


    public String translateToSystemPath( String nonSystemPath )
    {
        nonSystemPath = nonSystemPath.replace( '/', File.separatorChar );
        return nonSystemPath;
    }


    public Object runMethod(
        String classToLoad,
        String methodToTest,
        Class<?>[] methodToTestArgs,
        Object argsToTest ) throws InvocationTargetException
    {
        Class<?> rewrittenClass = loadClass( classToLoad );
        Method methodToRun = getClassMethod( rewrittenClass,
            methodToTest,
            methodToTestArgs );
        Object objectReturned = invokeMethod( methodToRun, argsToTest );
        return objectReturned;
    }


    private static Object invokeMethod( Method methodToRun, Object args )
        throws InvocationTargetException
    {
        Object createdObject = null;
        try
        {
            createdObject = (Object)methodToRun.invoke( null, (Object[])args );
        }
        catch ( IllegalArgumentException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch ( IllegalAccessException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return createdObject;
    }


    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static Method getClassMethod(
        Class rewrittenClass,
        String methodName,
        Class<?>[] args )
    {
        Method methodToRun = null;
        try
        {
            // Strange.....
            if ( args == null )
            {
                methodToRun = rewrittenClass.getDeclaredMethod( methodName,
                    (Class[])null );
            }
            else
            {
                methodToRun = rewrittenClass.getDeclaredMethod( methodName,
                    args );
            }
        }
        catch ( SecurityException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch ( NoSuchMethodException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return methodToRun;
    }


    private static Class<?> loadClass( String classToLoad )
    {
        try
        {
            return (Class<?>)virtualM.getLoader().loadClass( classToLoad );
        }
        catch ( ClassNotFoundException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}
